﻿/// <reference path="~/Scripts/FlowBasis/FlowBasis-all-vsdoc.js" />

FlowBasis.defineNamespace("Data");

FlowBasis.Data.RemoteResultSet = function (options) {
    this.url = options.url;
    this.query = options.query;

    if (options.maxResultsPerRequest) {
        this.maxResultsPerRequest = options.maxResultsPerRequest;
    }
    else {
        this.maxResultsPerRequest = 100;
    }

    this.currentResultSet = null;
    this.error = null;
};


FlowBasis.Data.RemoteResultSet.prototype.updateQuery = function (newQuery) {
    this.query = newQuery;

    this.currentResultSet = null;
    this.error = null;

    jQuery(this).trigger("queryUpdated");
};


FlowBasis.Data.RemoteResultSet.prototype.hasError = function () {
    return this.error != null;
};

FlowBasis.Data.RemoteResultSet.prototype.getError = function () {
    return this.error;
};

FlowBasis.Data.RemoteResultSet.prototype.canLoadMoreData = function () {
    var overallCount = this.getOverallCount();
    if (overallCount === null) {
        // We have not tried to load yet.
        return true;
    }
    else {
        var offset = this.getOffset();
        var count = this.getCount();
        var end = offset + count;
        if (end < overallCount) {
            return true;
        }
        else {
            if (this.currentResultSet.hasMoreData) {
                return true;
            }
            else {
                return false;
            }
        }
    }
};

FlowBasis.Data.RemoteResultSet.prototype.loadMoreData = function (offsetNeeded) {    
    var self = this;

    var currentOffset = this.getOffset();
    var offsetToLoad = currentOffset + this.getCount();

    if (typeof offsetNeeded != "undefined") {
        // Make sure we will have data we need.
        if (offsetNeeded < currentOffset) {
            offsetToLoad = offsetNeeded;
        }
        else if (offsetNeeded >= offsetToLoad + this.maxResultsPerRequest) {
            offsetToLoad = offsetNeeded;
        }
    }

    jQuery(this).trigger("beforeResultSetLoad");
    FlowBasis.Rpc.invoke(
        this.url,
        { query: this.query, offset: offsetToLoad, maxResults: this.maxResultsPerRequest },
        function (response, success) {
            if (success) {
                var newResultSet = response.result;

                if (self.currentResultSet == null) {
                    self.currentResultSet = newResultSet;
                }
                else {                    
                    var currentEnd = self.currentResultSet.offset + self.currentResultSet.data.length;
                    if (currentEnd == newResultSet.offset) {
                        // Combine result sets if contiguous.
                        var combinedResultSet = {};
                        combinedResultSet.offset = self.currentResultSet.offset;
                        combinedResultSet.data = self.currentResultSet.data.concat(newResultSet.data);
                        combinedResultSet.overallCount = newResultSet.overallCount;
                        combinedResultSet.hasMoreData = newResultSet.hasMoreData;

                        self.currentResultSet = combinedResultSet;
                    }
                    else {
                        // We did not load a contiguous block, so just use the new result set.
                        self.currentResultSet = newResultSet;
                    }
                }

                self.error = null;
            }
            else {
                self.error = response.error;
            }

            jQuery(self).trigger("afterResultSetLoad");
        });
};

FlowBasis.Data.RemoteResultSet.prototype.getEntry = function (index) {
    if (this.currentResultSet) {
        return this.currentResultSet.data[index - this.currentResultSet.offset];
    }
    else {
        return null;
    }
};

FlowBasis.Data.RemoteResultSet.prototype.getOffset = function () {
    if (this.currentResultSet) {
        return this.currentResultSet.offset;
    }
    else {
        return 0;
    }
};

FlowBasis.Data.RemoteResultSet.prototype.getCount = function () {
    if (this.currentResultSet) {
        return this.currentResultSet.data.length;
    }
    else {
        return 0;
    }
};

FlowBasis.Data.RemoteResultSet.prototype.getOverallCount = function () {
    if (this.currentResultSet) {
        if (typeof this.currentResultSet.overallCount != "undefined") {
            return this.currentResultSet.overallCount;
        }
        else {
            return this.data.length;
        }
    }
    else {
        return null;
    }
};